package com.miniapp.core.utils;



import com.miniapp.common.config.MiniappConfig;
import com.miniapp.common.config.PaicFtiWebDriverConfig;
import com.miniapp.common.gen.domain.PaicFtiAccount;
import com.miniapp.common.gen.domain.PaicFtiAccountExample;
import com.miniapp.common.gen.domain.PaicFtiPolicy;
import com.miniapp.common.gen.domain.PaicFtiPolicyExample;
import com.miniapp.common.gen.mapper.PaicFtiAccountMapper;
import com.miniapp.common.gen.mapper.PaicFtiPolicyMapper;
import com.miniapp.common.utils.file.FileUploadUtils;
import com.miniapp.common.utils.uuid.IdUtils;
import com.miniapp.framework.config.ServerConfig;
import org.apache.commons.collections4.CollectionUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 电子保单下载
 */
@Component
public class PaicFtiPolicyFileDownload {

    private Logger logger = LoggerFactory.getLogger(PaicLoginUtil.class);

    @Autowired
    private PaicLoginUtil paicLoginUtil;

    @Autowired
    private PaicFtiWebDriverConfig paicFtiWebDriverConfig;


    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private PaicFtiPolicyMapper paicFtiPolicyMapper;

    @Autowired
    private PaicFtiAccountMapper paicFtiAccountMapper;

    private static Lock lock = new ReentrantLock();


    /**
     * 下载电子保单
     * @param policyNo
     */
    @Async
    public void policyFileDownload(String policyNo){

        try {
            String policyPath = getPolicyDownloadPath(policyNo);
            File file = new File(policyPath);
            if(file.exists()){
                //移动电子保单+电子保单地址入库
                moveDownloadPolicy(policyNo);
                return;
            }

            lock.tryLock(100, TimeUnit.SECONDS);
            String downloadPolicyPaicftiAccount = paicFtiWebDriverConfig.getDownloadPolicyPaicftiAccount();
            ChromeDriver policyFileDownloadChromeDriver = getPolicyFileDownloadChromeDriver(downloadPolicyPaicftiAccount);


            //等待十秒钟看
            WebDriverWait webDriverWait = new WebDriverWait(policyFileDownloadChromeDriver,50);
            webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"mainSection\"]/section/div[1]/div/form/div/div[1]/div[2]/div/div/div/div/div/input")));


            //输入保单号
            WebElement policyNoInputElement = policyFileDownloadChromeDriver.findElementByXPath("//*[@id=\"mainSection\"]/section/div[1]/div/form/div/div[1]/div[2]/div/div/div/div/div/input");
            policyNoInputElement.clear();
            policyNoInputElement.sendKeys(policyNo);

            //查询按钮
            WebElement queryButton = policyFileDownloadChromeDriver.findElementByXPath("//*[@id=\"mainSection\"]/section/div[1]/div/form/div/div[4]/div[3]/button[1]");
            queryButton.click();
            ThreadUtils.threadSleep(5000);

            //选中保单
            WebElement radioElement = policyFileDownloadChromeDriver.findElementByXPath("//*[@id=\"mainSection\"]/section/div[3]/div/div/div[4]/div[2]/table/tbody/tr[1]/td[1]/div/label/span/input");
            radioElement.click();
            ThreadUtils.threadSleep(5000);

            //保单打印按钮 实际是保单下载
            WebElement downloadButton = policyFileDownloadChromeDriver.findElementByXPath("//*[@id=\"opr-area\"]/div/button[3]");
            downloadButton.click();
            ThreadUtils.threadSleep(5000);

            WebElement queren = policyFileDownloadChromeDriver.findElementByXPath("/html/body/div[8]/div[2]/div/div/div[3]/div/button[2]");
            queren.click();
            ThreadUtils.threadSleep(30000);
            //移动电子保单+电子保单地址入库
            moveDownloadPolicy(policyNo);
        }catch (Exception e){
            e.printStackTrace();
            logger.info("电子保单下载失败"+e.getMessage());
        }finally {
            lock.unlock();

        }


    }


    /**
     * 获取单证查页面的 ChromeDriver
     * @return
     */
    private ChromeDriver getPolicyFileDownloadChromeDriver(String account){
        //查询密码
        PaicFtiAccountExample paicFtiAccountExample = new PaicFtiAccountExample();
        paicFtiAccountExample.createCriteria().andUserNameEqualTo(account);
        List<PaicFtiAccount> paicFtiAccountList = paicFtiAccountMapper.selectByExample(paicFtiAccountExample);
        PaicFtiAccount paicFtiAccount = paicFtiAccountList.get(0);
        String password = paicFtiAccount.getPassword();

        //获取登录成功的ChromeDriver
        ChromeDriver chromeDriver = paicLoginUtil.login(account, password, IdUtils.fastUUID());

        //1、关掉弹窗
        ThreadUtils.threadSleep(2000);
        List<WebElement> posterList = chromeDriver.findElementsByXPath("/html/body/div[4]/div/i");
        if(CollectionUtils.isNotEmpty(posterList)){
            WebElement posterWebElement = posterList.get(0);
            posterWebElement.click();
            logger.info("关掉海报弹窗");
        }
        ThreadUtils.threadSleep(2000);
        //2、关提示
        List<WebElement> promptList = chromeDriver.findElementsByXPath("//*[@id=\"app\"]/div/div[1]/div/div/div[2]/div[7]/div/div/button[1]");
        if(CollectionUtils.isNotEmpty(promptList)){
            WebElement promptWebElement = promptList.get(0);
            promptWebElement.click();
            logger.info("关掉提示弹窗");
        }
        ThreadUtils.threadSleep(2000);

        // 3、定位到要悬停的元素( 单证查询及下载 )
        WebElement element = chromeDriver.findElement(By.xpath("//*[@id=\"app\"]/div/div[1]/div/div/div[2]/div[5]"));
        // 使用Actions类来执行鼠标悬停
        Actions actions = new Actions(chromeDriver);
        actions.moveToElement(element).perform();
        ThreadUtils.threadSleep(10000);
        logger.info("悬浮到（单证查询及下载）");

        //4、 保单查询及下载
        WebElement zaixiantoubao = chromeDriver.findElement(By.xpath("//*[@id=\"app\"]/div/div[1]/div/div/div[2]/div[5]/div/div[1]/div"));
        zaixiantoubao.click();
        ThreadUtils.threadSleep(10000);
        logger.info("点击 保单查询及下载 ");

        return chromeDriver;


    }

    /**
     * 移动电子保单+电子保单地址入库
     * @param policyNo
     */
    private void moveDownloadPolicy(String policyNo){

        String policyPath = getPolicyDownloadPath(policyNo);
        File file = new File(policyPath);
        if(!file.exists()){
            logger.info("保单号：{},下载完成后移动电子保单文件不存在", policyNo);
            return;
        }

        try {
            MultipartFile multipartFile = convert(file);
            // 上传文件路径
            String filePath = MiniappConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, multipartFile);
            String url = paicFtiWebDriverConfig.getSystemUrl() + fileName;

            //更新保单信息
            PaicFtiPolicyExample paicFtiPolicyExample = new PaicFtiPolicyExample();
            paicFtiPolicyExample.createCriteria().andPolicyNoEqualTo(policyNo);
            List<PaicFtiPolicy> paicFtiPolicyList = paicFtiPolicyMapper.selectByExample(paicFtiPolicyExample);
            if(CollectionUtils.isEmpty(paicFtiPolicyList)){
                logger.info("保单号：{}，移动电子保单，未查询到此保单",policyNo);
            }else {
                PaicFtiPolicy paicFtiPolicy = paicFtiPolicyList.get(0);
                paicFtiPolicy.setPolicyFileUrl(url);
                paicFtiPolicyMapper.updateByPrimaryKeySelective(paicFtiPolicy);
                logger.info("保单号{}，移动电子保单成功",policyNo);
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("保单号：{}，移动电子保单失败：{}",policyNo,e.getMessage());
        }
    }

    /**
     * file转MultipartFile
     * @param file
     * @return
     * @throws IOException
     */
    private static MultipartFile convert(File file) throws IOException {
        FileInputStream input = new FileInputStream(file);
        MultipartFile multipartFile = new MockMultipartFile("file",
                file.getName(), "text/plain", input);
        return multipartFile;
    }

    private String getPolicyDownloadPath(String policyNo){
        String chromeDownloadsPath = paicFtiWebDriverConfig.getChromeDownloadsPath();
        //中国平安财产保险股份有限公司_保单_13208023902757663769.pdf
        String chromeDownloadFileName = "中国平安财产保险股份有限公司_保单_"+policyNo+".pdf";
        String policyPath = chromeDownloadsPath + File.separator + chromeDownloadFileName;
        return policyPath;

    }












}
